package sf.j2tree.list;

/**
 * Created by ping on 2017-09-11.
 */
public class SeqListImpl<T> implements SeqList<T> {

    private static final int initCapacity = 8;
    private Object[] tables;

    private int size = 0;

    public SeqListImpl(Object[] tables) {
        this.tables = tables;
    }

    public SeqListImpl() {
        this.tables = new Object[initCapacity];
    }

    private void expansion() {
        int length = this.tables.length;
        if (this.size >= length) {
            Object[] tempTables = this.tables;
            this.tables = new Object[length * 2];
            System.arraycopy(tempTables, 0, this.tables, 0, length);
        }
    }

    public boolean isEmpty() {
        return size == 0 ? true : false;
    }

    public int length() {
        return size;
    }

    private boolean isValid(int index) {
        if (index < 0) {
            throw new IllegalArgumentException("参数不能为负数");
        }
        if (index >= size) {
            throw new IllegalArgumentException("数组越界");
        }
        return true;
    }

    public boolean add(int index, T t) {
        if (isValid(index)) {
            expansion();
            System.arraycopy(this.tables, index, this.tables, index + 1, this.size - index);
            this.tables[++index] = t;
            size++;
            return true;
        }
        return false;
    }

    public boolean add(T t) {
        expansion();
        this.tables[size++] = t;
        return true;
    }

    public T get(int index) {
        if (isValid(index)) {
            return (T) this.tables[index];
        }
        return null;
    }

    public T replace(int index, T t) {
        if (isValid(index)) {
            T old = (T) this.tables[index];
            this.tables[index] = t;
            return old;
        }
        return null;
    }

    public T remove(int index) {
        if (isValid(index)) {
            System.arraycopy(this.tables, index + 1, this.tables, index, this.size - index - 1);
            size--;
        }
        return null;
    }

    public boolean removeAll() {
        if (isEmpty()) {
            return true;
        }
        this.tables = new Object[length()];
        this.size = 0;
        return true;
    }

    public void clear() {
        this.tables = new Object[initCapacity];
        this.size = 0;
    }

    public boolean remove(T t) {
        int index = indexOf(t);
        if (index >= 0) {
            System.arraycopy(this.tables, index + 1, this.tables, index, this.size - index - 1);
            size--;
            return true;
        }
        return false;
    }

    public int indexOf(T t) {
        for (int i = 0; i < size; i++) {
            if (this.tables[i].equals(t)) {
                return i;
            }
        }
        return -1;
    }

    public boolean contains(T t) {
        if (indexOf(t) >= 0) {
            return true;
        }
        return false;
    }

    public int lastIndexOf() {
        return this.size - 1;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < size; i++) {
            sb.append(this.tables[i]).append(", ");
        }
        if (this.size > 0) {
            sb.deleteCharAt(sb.length() -1);
            sb.deleteCharAt(sb.length() -1);
        }

        sb.append("]");
        return sb.toString();
    }

    public static void main(String[] args) {
        SeqList<Integer> list = new SeqListImpl<>();
        int mm = 0;
        list.add(mm++ );
        list.add(mm++ );
        list.add(mm++ );
        list.add(mm++ );
        list.add(mm++ );
        System.out.println(list);
        list.add(1, 100);
        System.out.println(list);
        System.out.println(list.indexOf(3));
        System.out.println(list.length());
        list.add(3, 541);
        System.out.println(list);
        System.out.println(list.contains(541));
        System.out.println(list.get(4));
        list.replace(3, 128);
        System.out.println(list);
        list.remove(1);
        System.out.println(list);
        System.out.println(list.remove(new Integer(111)));
        System.out.println(list.removeAll());
        System.out.println(list.isEmpty());
        System.out.println(list);
    }
}
